<template>
  <el-container class="solve-layout">
    <!-- 左：题面（可滚动） -->
    <el-aside width="50%" class="left-pane">
      <div class="scroll-wrap">
        <!-- Tabs: 题目描述 / 题解 / 提交记录 -->
        <el-tabs v-model="activeTab" class="solve-tabs">
          <el-tab-pane label="题目描述" name="desc">
            <!-- 原题面内容放到这里 -->
            <h1 class="q-title">{{ question?.title }}</h1>

            <div class="meta">
              <el-avatar
                  :src="question?.userVO?.userAvatar || defaultAvatar"
                  size="small"
              />
              <span class="author">作者：{{ question?.userVO?.userName || '匿名用户' }}</span>
              <span class="time">创建：{{ formatDate(question?.createTime) }}</span>
              <span v-if="question?.updateTime" class="time">更新：{{ formatDate(question?.updateTime) }}</span>
            </div>

            <div class="tags">
              <el-tag v-for="(tag, i) in (question?.tags || [])" :key="i" class="tag">
                {{ tag }}
              </el-tag>
            </div>

            <div class="desc">
              <div v-if="markdownError" class="error">
                <el-alert title="Markdown 渲染错误" type="error" :description="markdownError" show-icon />
              </div>
              <div v-else-if="parsedContent">
                <MdPreview
                    :model-value="parsedContent"
                    :preview-theme="previewTheme"
                    :code-theme="codeTheme"
                    :no-toolbar="true"
                />
              </div>
              <div v-else>
                <el-skeleton :rows="6" animated />
              </div>
            </div>

            <el-descriptions title="判题配置" :column="3" border>
              <el-descriptions-item label="时间限制">{{ question?.judgeConfig?.timeLimit }} ms</el-descriptions-item>
              <el-descriptions-item label="内存限制">{{ formatMemoryLimit(question?.judgeConfig?.memoryLimit) }} MB</el-descriptions-item>
              <el-descriptions-item label="栈限制">{{ question?.judgeConfig?.stackLimit }} KB</el-descriptions-item>
            </el-descriptions>
          </el-tab-pane>

          <el-tab-pane label="题解" name="solution">
            <div class="placeholder">
              <el-empty description="题解功能开发中..." />
            </div>
          </el-tab-pane>

          <el-tab-pane label="提交记录" name="submissions">
            <div v-loading="loadingSubmissions">
              <div class="placeholder" v-if="!loadingSubmissions && submissionsList.length === 0">
                <el-empty description="暂无提交记录（你提交后会显示在这里）" />
              </div>

              <div v-else>
                <el-table :data="submissionsList" style="width:100%" border>
                  <el-table-column prop="id" label="提交ID" width="120" />
                  <el-table-column prop="language" label="语言" width="100">
                    <template #default="{ row }">
                      {{ row.language?.toUpperCase() || '-' }}
                    </template>
                  </el-table-column>
                  <el-table-column label="状态" width="120">
                    <template #default="{ row }">
                      <el-tag :type="getStatusTagType(row)">
                        {{ getStatusText(row) }}
                      </el-tag>
                    </template>
                  </el-table-column>
                  <el-table-column label="提交时间" width="180">
                    <template #default="{ row }">
                      {{ formatDate(row.createTime) }}
                    </template>
                  </el-table-column>
                  <el-table-column label="操作" width="120" fixed="right">
                    <template #default="{ row }">
                      <el-button type="text" size="small" @click="gotoSubmissionDetail(row)">查看</el-button>
                    </template>
                  </el-table-column>
                </el-table>
              </div>
            </div>
          </el-tab-pane>
        </el-tabs>
      </div>
    </el-aside>

    <!-- 右：编辑器 -->
    <el-main class="right-pane">
      <div class="editor-header">
        <el-select v-model="selectedLanguage" placeholder="选择语言" size="small" style="width: 160px">
          <el-option v-for="lang in supportedLanguages" :key="lang.value" :label="lang.label" :value="lang.value" />
        </el-select>
        <el-button type="info" size="small" icon="Refresh" @click="resetCode">重置代码</el-button>
      </div>

      <!-- 编辑器区域：使用 flex 填满剩余高度 -->
      <div class="editor-wrapper">
        <MonacoEditor
            v-if="editorReady"
            v-model:value="code"
            :language="selectedLanguage"
            theme="vs-dark"
            :options="editorOptions"
        />
      </div>

      <div class="actions">
        <el-button type="primary" :loading="submitting" :disabled="!code.trim()" @click="handleSubmit">
          {{ submitting ? '提交中...' : '提交代码' }}
        </el-button>
      </div>

      <div v-if="submissionResult" class="result-card">
        <el-divider content-position="left">提交结果</el-divider>
        <!-- 如果是后端写入数据库成功后，仅展示提交 id 与状态 -->
        <div v-if="submissionResult.status === 'submitted'">
          <el-alert type="success" title="提交已入库" :description="`提交ID：${submissionResult.submissionId}`" show-icon />
        </div>
        <div v-else-if="submissionResult.status === 'error'">
          <el-alert type="error" title="提交失败" :description="submissionResult.message || '未知错误'" show-icon />
        </div>

        <!-- 若未来有评测详情，可在这里显示 details -->
      </div>
    </el-main>
  </el-container>
</template>

<script setup lang="ts">
import { ref, watch, onMounted, onUnmounted } from 'vue'
import { useRoute } from 'vue-router'
import dayjs from 'dayjs'
import { ElMessage, ElMessageBox } from 'element-plus'
import { MdPreview } from 'md-editor-v3'
import 'md-editor-v3/lib/style.css'
import MonacoEditor from 'monaco-editor-vue3'

import type { QuestionVO, QuestionSubmit } from '../../../generated'
import { QuestionControllerService } from '../../../generated'
/* 新增：导入提交服务与类型（路径按你的生成代码放置位置） */
import { QuestionSubmitControllerService } from '../../../generated'
import type { QuestionSubmitAddRequest } from '../../../generated'
import { useUserStore } from '../../stores/user.ts'

const route = useRoute()
const userStore = useUserStore()
const id = Number(route.params.id)
const activeTab = ref('desc')  // 默认显示题目描述

const question = ref<QuestionVO | null>(null)
const loading = ref(false)
const loadingSubmissions = ref(false)

const code = ref('// 在这里写下你的解答...')
const selectedLanguage = ref('cpp')
const editorReady = ref(false)
const submitting = ref(false)
const submissionResult = ref<any>(null)

const markdownError = ref('')
const parsedContent = ref('')

const defaultAvatar = 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png'

// 提交记录列表
const submissionsList = ref<QuestionSubmit[]>([])

// 轮询定时器
let pollingTimer: number | null = null
const POLLING_INTERVAL = 3000 // 每3秒轮询一次

// 编辑器与主题
const supportedLanguages = [
  { label: 'C++', value: 'cpp' },
  { label: 'Java', value: 'java' },
  { label: 'Python', value: 'python' },
  { label: 'JavaScript', value: 'javascript' },
]
const editorOptions = {
  automaticLayout: true,
  fontSize: 14,
  minimap: { enabled: false },
  scrollBeyondLastLine: false,
  formatOnPaste: true,
  formatOnType: true,
  tabSize: 2,
  wordWrap: 'on',
}
const previewTheme = 'default'
const codeTheme = 'github'

// Util
const formatDate = (t?: string) => (t ? dayjs(t).format('YYYY-MM-DD HH:mm:ss') : '-')
const formatMemoryLimit = (v?: number) => (v == null ? '-' : (v / 1024).toFixed(0))

// 获取提交状态文本
const getStatusText = (submit: QuestionSubmit): string => {
  const status = submit.status
  const accepted = submit.accepted
  
  // status: 0-待判题、1-判题中、2-成功、3-失败
  if (status === 0) return '待判题'
  if (status === 1) return '判题中'
  if (status === 2) {
    // accepted: 1代表AC，2代表WA
    if (accepted === 1) return '通过'
    if (accepted === 2) return '答案错误'
    return '成功'
  }
  if (status === 3) return '失败'
  return '未知'
}

// 获取提交状态标签类型
const getStatusTagType = (submit: QuestionSubmit): string => {
  const status = submit.status
  const accepted = submit.accepted
  
  if (status === 2 && accepted === 1) return 'success' // AC
  if (status === 2 && accepted === 2) return 'danger' // WA
  if (status === 3) return 'danger' // 失败
  if (status === 1) return 'warning' // 判题中
  return 'info' // 待判题
}

// 内容解析
const parseContent = (content: string) => {
  try {
    const parsed = JSON.parse(content)
    parsedContent.value = typeof parsed === 'string' ? parsed : content
  } catch {
    parsedContent.value = content
  }
}

// 重置代码
const getDefaultCodeTemplate = (lang: string) => {
  const tpl: Record<string, string> = {
    cpp: `// 请在此处编写你的解答
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        return {};
    }
};`,
    java: `// 请在此处编写你的解答
import java.util.*;
class Solution {
    public int[] twoSum(int[] nums, int target) {
        return new int[0];
    }
}`,
    python: `# 请在此处编写你的解答
from typing import List
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        pass`,
    javascript: `// 请在此处编写你的解答
/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function(nums, target) {
};`,
  }
  return tpl[lang] || '// 请在此处编写你的解答'
}
const resetCode = () => {
  code.value = getDefaultCodeTemplate(selectedLanguage.value)
}

/**
 * 检查是否有待判题的记录（status = 0 或 1）
 */
const hasPendingSubmissions = (): boolean => {
  return submissionsList.value.some(submit => {
    const status = submit.status
    return status === 0 || status === 1
  })
}

/**
 * 启动轮询
 */
const startPolling = () => {
  // 如果已经有定时器在运行，先清除
  stopPolling()
  
  // 检查是否有待判题的记录
  if (!hasPendingSubmissions()) {
    return
  }
  
  // 启动轮询
  pollingTimer = window.setInterval(() => {
    // 如果当前不在提交记录tab，不进行轮询（节省资源）
    if (activeTab.value !== 'submissions') {
      return
    }
    
    // 如果已经没有待判题的记录，停止轮询
    if (!hasPendingSubmissions()) {
      stopPolling()
      return
    }
    
    // 静默刷新提交记录（不显示loading）
    fetchSubmissionsSilently()
  }, POLLING_INTERVAL)
}

/**
 * 停止轮询
 */
const stopPolling = () => {
  if (pollingTimer !== null) {
    clearInterval(pollingTimer)
    pollingTimer = null
  }
}

/**
 * 静默获取提交记录（用于轮询，不显示loading）
 */
const fetchSubmissionsSilently = async () => {
  if (!id) return
  try {
    const res = await QuestionSubmitControllerService.questionSubmitQueryByUserIdAndQuestionId(id)
    if (res.code === 0 && res.data) {
      // 按创建时间倒序排列（最新的在前）
      const newList = res.data.sort((a, b) => {
        const timeA = a.createTime ? new Date(a.createTime).getTime() : 0
        const timeB = b.createTime ? new Date(b.createTime).getTime() : 0
        return timeB - timeA
      })
      
      // 检查更新前是否有待判题记录
      const hadPending = hasPendingSubmissions()
      
      // 更新提交记录列表
      submissionsList.value = newList
      
      // 检查更新后是否还有待判题记录
      const hasPendingNow = hasPendingSubmissions()
      
      // 如果之前有待判题记录，现在没有了，说明判题完成，停止轮询
      if (hadPending && !hasPendingNow) {
        stopPolling()
        // 可选：显示一个提示，告知用户判题已完成
        // ElMessage.success('判题已完成')
      }
    }
  } catch (e) {
    console.error('轮询获取提交记录异常：', e)
    // 轮询失败时不显示错误提示，避免打扰用户
    // 但可以停止轮询，避免持续失败
    stopPolling()
  }
}

/**
 * 获取提交记录
 */
const fetchSubmissions = async () => {
  if (!id) return
  loadingSubmissions.value = true
  try {
    const res = await QuestionSubmitControllerService.questionSubmitQueryByUserIdAndQuestionId(id)
    if (res.code === 0 && res.data) {
      // 按创建时间倒序排列（最新的在前）
      submissionsList.value = res.data.sort((a, b) => {
        const timeA = a.createTime ? new Date(a.createTime).getTime() : 0
        const timeB = b.createTime ? new Date(b.createTime).getTime() : 0
        return timeB - timeA
      })
      
      // 检查是否需要启动轮询
      if (hasPendingSubmissions()) {
        startPolling()
      } else {
        stopPolling()
      }
    } else {
      ElMessage.error(res.message || '获取提交记录失败')
    }
  } catch (e) {
    console.error('获取提交记录异常：', e)
    ElMessage.error('网络错误，获取提交记录失败')
  } finally {
    loadingSubmissions.value = false
  }
}

/**
 * handleSubmit
 *  - 调用后端写入提交记录接口
 *  - 提交成功后立即获取最新的提交记录并跳转到提交记录tab
 */
const handleSubmit = async () => {
  if (!code.value.trim()) return
  if (!id) {
    ElMessage.error('题目ID异常，无法提交')
    return
  }
  
  if (!userStore.user) {
    ElMessage.warning('请先登录')
    return
  }

  submitting.value = true
  submissionResult.value = null

  try {
    const payload: QuestionSubmitAddRequest = {
      code: code.value,
      language: selectedLanguage.value,
      questionId: id,
    }

    const res = await QuestionSubmitControllerService.doQuestionSubmit(payload)

    // 常见项目生成的 BaseResponse 格式：{ code: 0, data: ..., message: ... }
    if (res && (res as any).code === 0) {
      const submissionId = (res as any).data
      
      // 设置提交结果
      submissionResult.value = { status: 'submitted', submissionId }
      ElMessage.success(`提交成功（ID: ${submissionId}）`)
      
      // 立即跳转到提交记录tab
      activeTab.value = 'submissions'
      
      // 延迟一下再获取提交记录，确保后端已保存
      setTimeout(() => {
        fetchSubmissions()
        // 提交成功后启动轮询
        startPolling()
      }, 500)
    } else {
      // 非 0 code 视作失败
      const msg = (res as any)?.message || '提交失败'
      submissionResult.value = { status: 'error', message: msg }
      ElMessage.error(msg)
    }
  } catch (e) {
    console.error('提交异常：', e)
    submissionResult.value = { status: 'error', message: '网络错误，提交失败' }
    ElMessage.error('网络错误，提交失败')
  } finally {
    submitting.value = false
  }
}

// 点击"查看"显示提交详情
const gotoSubmissionDetail = (submit: QuestionSubmit) => {
  if (!submit.code) {
    ElMessage.warning('无法查看代码')
    return
  }
  // 可以打开一个对话框显示代码和判题信息
  ElMessageBox.alert(
    `<div style="text-align: left;">
      <p><strong>提交ID:</strong> ${submit.id}</p>
      <p><strong>语言:</strong> ${submit.language}</p>
      <p><strong>状态:</strong> ${getStatusText(submit)}</p>
      <p><strong>提交时间:</strong> ${formatDate(submit.createTime)}</p>
      <pre style="background: #f5f5f5; padding: 10px; border-radius: 4px; overflow-x: auto; max-height: 400px;">${submit.code}</pre>
    </div>`,
    '提交详情',
    {
      dangerouslyUseHTMLString: true,
      confirmButtonText: '关闭',
    }
  )
}

// 获取题目详情
const fetchQuestion = async () => {
  if (!id) return
  loading.value = true
  markdownError.value = ''
  parsedContent.value = ''
  try {
    const res = await QuestionControllerService.getQuestionVoById(id)
    if (res.code === 0 && res.data) {
      question.value = res.data
      parseContent(res.data.content || '')
      resetCode()
    } else {
      ElMessage.error(res.message || '获取题目失败')
    }
  } catch (e) {
    ElMessage.error('网络错误，请重试')
  } finally {
    loading.value = false
  }
}

onMounted(() => {
  // 小延迟确保容器渲染，monaco 挂载更稳定
  setTimeout(() => (editorReady.value = true), 60)
  fetchQuestion()
  // 如果用户已登录，获取提交记录
  if (userStore.user) {
    fetchSubmissions()
  }
})

// 组件卸载时清理定时器
onUnmounted(() => {
  stopPolling()
})

// 监听用户登录状态，如果登录了则获取提交记录
watch(() => userStore.user, (user) => {
  if (user && id) {
    fetchSubmissions()
  } else {
    // 用户退出登录时停止轮询
    stopPolling()
  }
})

// 监听提交记录tab的切换，当切换到提交记录tab时，如果有待判题记录则启动轮询
watch(() => activeTab.value, (newTab) => {
  if (newTab === 'submissions') {
    // 切换到提交记录tab时，检查是否需要启动轮询
    if (hasPendingSubmissions()) {
      startPolling()
    }
  } else {
    // 切换到其他tab时停止轮询（节省资源）
    stopPolling()
  }
})

watch(() => selectedLanguage.value, (v) => (code.value = getDefaultCodeTemplate(v)))
</script>

<style scoped>
/* 让 solve-layout 填满父容器（BasicLayout 的 .layout-main 会被设置为 overflow:hidden） */
.solve-layout {
  height: 100%;
  min-height: 0; /* 允许子元素使用 flex + min-height:0 */
  display: flex;
}

/* 左侧题面 */
.left-pane {
  border-right: 1px solid #eee;
  padding: 16px 20px;
  min-height: 0;
}

/* 关键：左侧内部区域充满高度并独立滚动 */
.scroll-wrap {
  height: 100%;
  overflow-y: auto;
  min-height: 0;
  padding-right: 8px;
}

/* 右侧编辑器区域：使用 flex 布局把编辑器撑满可用高度 */
.right-pane {
  padding: 16px 20px;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

/* 编辑器容器占据右侧剩余空间（不会产生页面滚动） */
.editor-wrapper {
  flex: 1;
  min-height: 0;
  position: relative;
  background: #1e1e1e;
  border: 1px solid #ebeef5;
  border-radius: 8px;
  overflow: hidden;
}

/* 让 Monaco 编辑器自身完全填充 wrapper（避免使用 position:absolute 导致布局问题） */
:deep(.monaco-editor) {
  width: 100% !important;
  height: 100% !important;
  position: relative !important;
}

/* 其余样式（略微调整） */
.q-title {
  font-size: 20px;
  font-weight: 700;
  margin-bottom: 12px;
}
.meta {
  display: flex;
  align-items: center;
  gap: 10px;
  color: #606266;
  font-size: 13px;
  margin-bottom: 10px;
}
.tags {
  margin: 10px 0 16px;
}
.tag {
  margin-right: 6px;
  margin-bottom: 4px;
}
.desc {
  background: #fff;
  border: 1px solid #ebeef5;
  border-radius: 8px;
  padding: 16px;
  margin-bottom: 16px;
}
.editor-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-bottom: 8px;
}
.actions {
  margin: 12px 0;
  text-align: left;
}
.result-card {
  margin-top: 8px;
  padding: 12px;
  border: 1px solid #ebeef5;
  border-radius: 8px;
  background: #fff;
}
.solve-tabs {
  /* 让 tab 占满 scroll-wrap 宽度 */
  width: 100%;
}

.placeholder {
  padding: 20px;
  text-align: center;
  color: #909399;
}
</style>
